package com.dominator.utils.encode;

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;

import com.dominFramework.core.typewrap.Dto;
import com.dominFramework.core.typewrap.Dtos;
import com.dominator.utils.system.PropertiesLoader;
import com.google.gson.Gson;
import org.apache.commons.codec.binary.Hex;

public class WzlEncryptUtil {


    public static PropertiesLoader propertiesLoader = new PropertiesLoader("sysconfig.properties");


    private static String KEY_ALGORITHM = "AES";
    private static String RANDOM_ALGORITHM = "SHA1PRNG";
    private static String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static String CHARSET_NAME = "UTF-8";
    private static WzlEncryptUtil instance = null;
    private Cipher encryptCipher = null;
    private Cipher decryptCipher = null;
    // TODO 加密KEY(我方提供并定期更换)
    public static String sKey = propertiesLoader.getProperty("wzl_skey"); //开发时用



    static {
        // 初始化加密对象
        WzlEncryptUtil.getInstance();
    }

    private WzlEncryptUtil(String key) {
        // 初始化加密对象
        try {
            initCipher(sKey);
        } catch (Exception e) {
            System.out.println("加密对象初始化失败！");
            e.printStackTrace();
        }
    }

    public static WzlEncryptUtil getInstance() {
        if (instance == null) {
            instance = new WzlEncryptUtil(sKey);
        }
        return instance;
    }

    /**
     * 初始化加解密对象
     *
     * @param key
     * @throws Exception
     */
    private void initCipher(String key) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
        SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
        random.setSeed(key.getBytes());
        kgen.init(128, random);
        SecretKeySpec skeySpec = new SecretKeySpec(kgen.generateKey().getEncoded(), KEY_ALGORITHM);
        encryptCipher = Cipher.getInstance(CIPHER_ALGORITHM);
        encryptCipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        decryptCipher = Cipher.getInstance(CIPHER_ALGORITHM);
        decryptCipher.init(Cipher.DECRYPT_MODE, skeySpec);
    }

    /**
     * 加密
     * @param sSrc 报文
     * @return
     * @throws Exception
     */
    public String encrypt(String sSrc) throws Exception {
        byte[] encrypted = encryptCipher.doFinal(sSrc.getBytes(CHARSET_NAME));
        String encrypt = Hex.encodeHexString(encrypted);
        return encrypt.toUpperCase();
    }

    /**
     * 解密
     * @param sSrc 报文
     * @return
     * @throws Exception
     */
    public String decrypt(String sSrc) throws Exception {
        try {
            byte[] encrypted = Hex.decodeHex(sSrc.toCharArray());
            byte[] original = decryptCipher.doFinal(encrypted);
            String originalString = new String(original, CHARSET_NAME);
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }

    public static String msg1 = "新浪财经讯 乐视网(12.420, -1.38, -10.00%)今日再现大宗交易，成交金额1242万元，成交100万股；买方为华泰证券(21.110, -0.55, -2.54%)深圳益田路荣超商务中心证券营业部，卖方为中泰证券宁波江东北路证券营业部。";
    public static String msg2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg><head sid=\"DDTZ\" pid=\"test\" version=\"1.0\" time=\"20180125151013\"/><body>"
            + "<ticketorder lotteryId=\"JCZQHH\" ticketsnum=\"1\" totalmoney=\"10\"><tickets><ticket ticketId=\"test0001\" betType=\"P4_1\" "
            + "scheduleId=\"20180125\" betUnits=\"1\" multiple=\"5\" betMoney=\"10\" isAppend=\"0\" isFreePass=\"0\"><betContent>RQSPF@4-001:[平]/SPF@4-002:[平]/"
            + "SPF@4-004:[胜]/RQSPF@4-006:[胜]</betContent></ticket></tickets></ticketorder></body></msg>";
    public static String msg3 = "Creates a standard password-based bytes encryptor using 256 bit AES encryption with\n"
            + "\t * Galois Counter Mode (GCM). Derives the secret key using PKCS #5's PBKDF2\n"
            + "\t * (Password-Based Key Derivation Function #2). Salts the password to prevent\n"
            + "\t * dictionary attacks against the key. The provided salt is expected to be\n"
            + "\t * hex-encoded; it should be random and at least 8 bytes in length. Also applies a\n"
            + "\t * random 16 byte initialization vector to ensure each encrypted message will be\n" + "\t * unique. Requires Java 6.";
    public static String[] msgs = new String[] { msg1, msg2, msg3 };

    public static void main(String[] args) throws Exception {
        // 加密
        Dto dto=Dtos.newDto("phoneNum","13367085890");
        String msg1=new Gson().toJson(dto);
        System.out.println("加密前:"+msg1);
    	String enString1 = WzlEncryptUtil.getInstance().encrypt(msg1);
        System.out.println("加密后的内容："+enString1);
        String msg= "AB2EE05799A3041153AFCC60C609B90E";
        String encode2 = WzlEncryptUtil.getInstance().decrypt(msg);
        System.out.println("msg解密后："+encode2);
    }
}
